# ============================================================
# * Copyright © hk. 2022-2025. All rights reserved.
# * File name: CMakeLists.txt
# * Author   : 苏木
# * Date     : 2025-05-22
# * Version  : 
# * Description: cmake version 3.16.3
# ============================================================
## https://cmake.com.cn/cmake/help/latest/guide/tutorial/index.html
## https://cmake.org/cmake/help/latest/

# 指定 CMake 的最低版本要求
# --------------------------------------------------
cmake_minimum_required(VERSION 3.10)


# 设置项目名称和使用的编程语言
# --------------------------------------------------
project(SPROJECT C)


# 指定可执行程序和源文件
# --------------------------------------------------
add_executable(app_demo.out main.c)


# 1. 处理文件名和路径
# --------------------------------------------------
# get_filename_component(outVar input component [CACHE])
# outVar    调用的结果存储在outVar变量中。
# CACHE     关键字是可选的。如果存在，则结果存储为缓存变量而不是常规变量。通常，不希望将结果存储在缓存中，因此不需要使用CACHE关键字。
# component 要从输入中提取的component由组件指定，组件必须是以下组件之一
# 			 	DIRECTORY 提取输入的路径部分，但不包含文件名。CMake 2.8.12之前，这个选项是PATH，为了保持与旧版本的兼容性，它仍然接受为DIRECTORY的同义词。
# 			 	NAME      取完整的文件名，包括扩展名。这实际上只是丢弃了输入的目录部分。
#			 	NAME_WE   只提取基本文件名。这是类似的名称，除了只有文件名的一部分，但不包括提取的第一个“.”。
# 				EXT       这是NAME_WE的补充。它从第一个"."开始提取文件名的扩展部分。
message(STATUS "==> ${CMAKE_VERSION} 1.1 get_filename_component()处理文件名和路径")
set(input /some/path/foo.bar.txt)
get_filename_component(path1 ${input} DIRECTORY)  # /some/path
message(STATUS "[USER:TOP]path1 : ${path1}")

get_filename_component(path2 ${input} PATH)       # /some/path
message(STATUS "[USER:TOP]path2 : ${path2}")

get_filename_component(fullName ${input} NAME)    # foo.bar.txt
message(STATUS "[USER:TOP]fullName : ${fullName}")

get_filename_component(baseName ${input} NAME_WE) # foo
message(STATUS "[USER:TOP]baseName : ${baseName}")

get_filename_component(extension ${input} EXT)    # .bar.txt
message(STATUS "[USER:TOP]extension : ${extension}")

message("")

# 2. 获取绝对路径
# --------------------------------------------------
# get_filename_component(outVar input component [BASE_DIR dir] [CACHE])
# input    输入可以是相对路径，也可以是绝对路径。
# BASE_DIR 如果给定了BASE_DIR，相对路径将解释为相对于dir而不是当前源目录(即CMAKE_CURRENT_SOURCE_DIR)。如果输入已经是绝对路径，则忽略BASE_DIR。

# 示例 1: 获取当前 CMakeLists.txt 文件的绝对路径
message(STATUS "==> ${CMAKE_VERSION} 2.1 获取当前 CMakeLists.txt 文件的绝对路径")
get_filename_component(
    CURRENT_SCRIPT_ABSPATH        # 存储结果的变量名
    "${CMAKE_CURRENT_LIST_FILE}"  # 输入文件名（这里是当前 CMakeLists.txt）
    ABSOLUTE                      # 转换为绝对路径
)
message(STATUS "[USER:TOP]CMakeLists.txt absolute path: ${CURRENT_SCRIPT_ABSPATH}")
message("")
# 输出如下：
# -- ==> 3.16.3 2.1 获取当前 CMakeLists.txt 文件的绝对路径
# -- [USER:TOP]CMakeLists.txt absolute path: /home/sumu/Linux/CMake-Practice-zh-CN/cmake-demo/02_command/03_file_process/01_get_filename_component/CMakeLists.txt

# 示例 2: 获取源代码目录下某个文件的绝对路径
message(STATUS "==> ${CMAKE_VERSION} 2.2 获取源代码目录下某个文件的绝对路径")
set(RELATIVE_FILE "main.c")  # 假设有一个相对路径文件
get_filename_component(
    ABS_FILE
    "${RELATIVE_FILE}"
    ABSOLUTE
    BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}"  # 基目录（若不提供，默认使用当前工作目录）
)
message(STATUS "[USER:TOP]file main.c absolute path: ${ABS_FILE}")
message("")
# 输出如下：
# -- ==> 3.16.3 2.2 获取源代码目录下某个文件的绝对路径
# -- [USER:TOP]file main.c absolute path: /home/sumu/Linux/CMake-Practice-zh-CN/cmake-demo/02_command/03_file_process/01_get_filename_component/main.c

# 示例 3: 分解路径组件
message(STATUS "==> ${CMAKE_VERSION} 2.3 分解路径组件")
get_filename_component(
    PARENT_DIR
    "${CMAKE_CURRENT_SOURCE_DIR}"
    DIRECTORY  # 获取父目录
)

message(STATUS "[USER:TOP]parent absolute path: ${PARENT_DIR}")
message("")
# 输出如下：
# -- ==> 3.16.3 2.3 分解路径组件
# -- [USER:TOP]parent absolute path: /home/sumu/Linux/CMake-Practice-zh-CN/cmake-demo/02_command/03_file_process

# 3. 提取完整命令行的部分内容
# --------------------------------------------------
# get_filename_component(progVar input PROGRAM [PROGRAM_ARGS argVar] [CACHE])
# 在这个形式中，假设输入是一个可能包含参数的命令行。
# CMake将提取可执行文件的完整路径，该路径将由指定的命令行调用，必要时使用PATH环境变量解析可执行文件的位置，
# 并将结果存储在progVar中。如果给定PROGRAM_ARGS，命令行参数集也将作为列表存储在由argVar变量中。
# CACHE关键字与get_filename_component()的其他形式具有相同的含义。
